using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using needle.UI.Controls.Flat.Utilities;
using needle.UI.Controls.Flat.Resources;
using needle.UI.Controls.Flat.Resources.Keys;
using needle.UI.Controls.Flat.Utilities.Win32;
using needle.UI.Controls.Flat.Windows.Forms.Helpers;

namespace needle.UI.Controls.Flat.Windows.Forms
{
	#region DatePicker

	[DefaultEvent("DateChanged"),
	 System.ComponentModel.ToolboxItem(true)]
	public class DatePicker : ButtonEdit
	{
		private System.ComponentModel.Container components   = null;
		private ImageDatePickerPopUp m_DatePickerPopUp  = null;
		private Icon mButtonIcon = null;

		//Style Neo, Default
		private Color m_CalendarTitleBackColor = Color.FromArgb(170, 170, 221);
		private Color m_CalendarTitleForeColor = Color.White;
		private Color m_CalendarTrailingForeColor = Color.Silver;
		private Color m_CalendarBackColor = Color.White;
		private Color m_CalendarForeColor = Color.Black;

		[Category("Behavior")]
		public event System.EventHandler DateChanged = null;

		#region Constructors
		public DatePicker()
		{
			InitializeComponent();
			mButtonIcon = GraphicsUtils.LoadIcon("down.ico");
		
			this.Mask  = EditMask.Date;
			this.Value = DateTime.Today;

			mpTextBox.LostFocus += new System.EventHandler(this.m_pTextBox_OnLostFocus);
		}
		#endregion

		#region Dispose
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
		#endregion

		#region Component Designer generated code
		private void InitializeComponent()
		{
			this.SuspendLayout();
			// 
			// mpTextBox
			// 
			this.mpTextBox.Size = new System.Drawing.Size(65, 13);
			this.mpTextBox.ProccessMessage += new MessageEventHandler(this.m_pTextBox_ProccessMessage);
			// 
			// DatePicker
			// 
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.mpTextBox});
			this.Name = "DatePicker";
			this.Size = new System.Drawing.Size(88, 19);
			this.ResumeLayout(false);

		}
		#endregion

		#region Events handlers

		private void OnPopUpSelectionChanged(object sender,DateChangedEventArgs e)
		{
			this.Value = e.Date;			
		}

		private void m_pTextBox_ProccessMessage(object sender, MessageEventArgs e)
		{
			Message m = e.WindowsMessage;

			if(mDroppedDown && m_DatePickerPopUp != null && IsNeeded(ref m))
			{
				m_DatePickerPopUp.PostMessage(ref m);
				e.Result = true;
			}

			e.Result = false;
		}

		private void m_pTextBox_OnLostFocus(object sender, System.EventArgs e)
		{
			if((mDroppedDown && m_DatePickerPopUp != null) && 
			   (this.ParentForm.ActiveControl != this ||
				Form.ActiveForm != this.ParentForm && Form.ActiveForm != this.m_DatePickerPopUp))
			{
				m_DatePickerPopUp.Close();
				mDroppedDown = false;
			}
		}

		private void OnPopUpVisibleChanged(object sender,System.EventArgs e)
		{
			mDroppedDown = false;
			Invalidate(false);

			if(!this.ContainsFocus)
			{
				this.BackColor = StyleGuide.InteliEditColor(this.mpTextBox.ReadOnly,this.Enabled, base.EditColor,
					base.EditReadOnlyColor, base.EditDisabledColor);
			}
		}

		#endregion

		#region Virtuals

		protected void OnDateChanged()
		{
			if(this.DateChanged != null)
			{
				this.DateChanged(this,new System.EventArgs());
			}
		}

		#endregion

		#region Overrides

		private void OnPopUpClosed(object sender,System.EventArgs e)
		{
			mDroppedDown = false;
			m_DatePickerPopUp.Dispose();
			Invalidate(false);
		}

		protected override void OnButtonPressed(EventArgs e)
		{
			if(mDroppedDown || this.ReadOnly)
			{
				m_DatePickerPopUp.Close();
				return;
			}	
		
			ShowPopUp();			
		}

		protected override void OnPlusKeyPressed()
		{
			base.OnPlusKeyPressed();

			if(mDroppedDown || this.ReadOnly)
			{
				return;
			}	
		
			ShowPopUp();			
		}

		protected override void OnEnterKeyPressed()
		{				
			if(mDroppedDown && m_DatePickerPopUp != null)
			{
				this.Value = m_DatePickerPopUp.SelectedDate;
				m_DatePickerPopUp.Close();
			}
			else
			{
				OnDateChanged();
			}

			this.OnKeyDown(new KeyEventArgs(Keys.Enter));
			this.OnKeyPress(new KeyPressEventArgs((char)13));
		}

		protected override void OnKeyDown(KeyEventArgs e)
		{
			base.OnKeyDown(e);

			if (e.Alt && e.KeyCode == Keys.Down)
				this.ShowPopUp();
			else if ((e.Alt && e.KeyCode == Keys.Up) || (e.KeyCode == Keys.Escape)) 
			{
				if(mDroppedDown && m_DatePickerPopUp != null)
				{
					m_DatePickerPopUp.Close();
					mDroppedDown = false;
				}
			}
		}

		protected override void OnStyleChanged(object sender, StyleEventArgs args)
		{
			base.OnStyleChanged(sender, args);

			if (args.PropertyName == "CalendarTitleBackColor") {this.FlashColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "CalendarTitleForeColor") {this.TextColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "CalendarTrailingForeColor") {this.EditColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "CalendarBackColor") {this.EditFocusedColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "CalendarForeColor") {this.EditReadOnlyColor = (Color)args.PropertyValue;}

			this.Invalidate(true);
		}

		protected override void OnPlansOfColorsChanged(object sender, PlansOfColorsChangedEventArgs args)
		{
			base.OnPlansOfColorsChanged(sender, args);

			if (this.Style!=null)
			{
				this.CalendarTitleBackColor = this.Style.CalendarTitleBackColor;
				this.CalendarTitleForeColor = this.Style.CalendarTitleForeColor;
				this.CalendarTrailingForeColor = this.Style.CalendarTrailingForeColor;
				this.CalendarBackColor = this.Style.CalendarBackColor;
				this.CalendarForeColor = this.Style.CalendarForeColor;
			}

			this.Invalidate(true);
		}
		#endregion

		#region Internal helpers

		[UseApiElements("ShowWindow")]
		private void ShowPopUp()
		{
			Point pt = this.Parent.PointToScreen(new Point(this.Left,this.Bottom + 1));
			m_DatePickerPopUp = new ImageDatePickerPopUp(this,this.Value);
			m_DatePickerPopUp.SelectionChanged += new DateSelectionChangedEventHandler(this.OnPopUpSelectionChanged);
			m_DatePickerPopUp.Closed += new System.EventHandler(this.OnPopUpClosed);
	
			Rectangle screenRect = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
			if(screenRect.Bottom < pt.Y + m_DatePickerPopUp.Height)
			{
				pt.Y = pt.Y - m_DatePickerPopUp.Height - this.Height - 1;
			}

			if(screenRect.Right < pt.X + m_DatePickerPopUp.Width)
			{
				pt.X = screenRect.Right - m_DatePickerPopUp.Width - 2;
			}

			m_DatePickerPopUp.Location = pt;

			User32.ShowWindow(m_DatePickerPopUp.Handle,4);

			m_DatePickerPopUp.Start = true;
			mDroppedDown = true;
		}

		[UseApiElements("WM_MOUSEWHEEL, WM_KEYUP, WM_KEYDOWN, WM_CHAR")]
		private bool IsNeeded(ref  System.Windows.Forms.Message m)
		{
			if(m.Msg == (int)Msgs.WM_MOUSEWHEEL)
			{
				return true;
			}

			if(m.Msg == (int)Msgs.WM_KEYUP || m.Msg == (int)Msgs.WM_KEYDOWN)
			{
				return true;
			}

			if(m.Msg == (int)Msgs.WM_CHAR)
			{
				return true;
			}

			return false;
		}

		#endregion

		#region Properties

		protected override Icon ButtonIcon
		{
			get{return this.mButtonIcon;}
		}
		
		[Category("Style")]
		public Color CalendarTitleBackColor
		{
			get {return m_CalendarTitleBackColor;}
			set 
			{
				m_CalendarTitleBackColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color CalendarTitleForeColor
		{
			get {return m_CalendarTitleForeColor;}
			set 
			{
				m_CalendarTitleForeColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color CalendarTrailingForeColor
		{
			get {return m_CalendarTrailingForeColor;}
			set 
			{
				m_CalendarTrailingForeColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color CalendarBackColor
		{
			get {return m_CalendarBackColor;}
			set 
			{
				m_CalendarBackColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color CalendarForeColor
		{
			get {return m_CalendarForeColor;}
			set 
			{
				m_CalendarForeColor = value;
				this.Invalidate();
			}
		}

		[Category("Appearance")]
		public DateTime Value {
			get {
                return mpTextBox.DateValue;
            }
			set	{

                mpTextBox.DateValue = value;
                OnDateChanged();

                switch (mDateTimeFormat) {
                    case DateTimePickerFormat.Long:
                        mpTextBox.Text = value.ToLongDateString();
                        break;
                    case DateTimePickerFormat.Short:
                        mpTextBox.Text = value.ToShortDateString();
                        break;
                    case DateTimePickerFormat.Time:
                        mpTextBox.Text = value.ToLongTimeString();
                        break;
                    case DateTimePickerFormat.Custom:
                        //return value.ToString(mFormat);
                        mpTextBox.Text = value.ToString();
                        break;
                }

			}

		}

        DateTimePickerFormat mDateTimeFormat = DateTimePickerFormat.Short;
        [Category("Appearance")]
        public DateTimePickerFormat DateTimeFormat {
            get { return mDateTimeFormat; }
            set {
                mDateTimeFormat = value;
            }
        }

		[Category("Behavior"),
		 Browsable(false)]
		public new EditMask Mask {
			get{ return mpTextBox.Mask; }
			set{ mpTextBox.Mask = value; }
		}

		#endregion
	}

	#endregion

	#region MonthCalendar

	[System.ComponentModel.ToolboxItem(false)]
	internal class MonthCalendar : System.Windows.Forms.MonthCalendar
	{
		private System.ComponentModel.Container components   = null;

		#region Constructors
		public MonthCalendar()
		{
			InitializeComponent();
		}
		#endregion

		#region Dispose
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
		#endregion

		#region Component Designer generated code
		private void InitializeComponent()
		{
			// 
			// MonthCalendar
			// 
			this.AnnuallyBoldedDates = new System.DateTime[0];
			this.BoldedDates = new System.DateTime[0];
			this.MonthlyBoldedDates = new System.DateTime[0];
			this.SelectionRange = new System.Windows.Forms.SelectionRange(new System.DateTime(2002, 5, 7, 0, 0, 0, 0), new System.DateTime(2002, 5, 7, 0, 0, 0, 0));
			this.DateChanged += new System.Windows.Forms.DateRangeEventHandler(this.EnterpriseMonthCalendar_DateChanged);

		}
		#endregion

		#region Events helpers
		private void EnterpriseMonthCalendar_DateChanged(object sender, System.Windows.Forms.DateRangeEventArgs e)
		{
			this.SetSelectionRange(this.SelectionRange.Start,this.SelectionRange.Start);
		}
		#endregion

		#region Overrides
		protected override void WndProc(ref Message m)
		{			
			base.WndProc(ref m);
		}
		#endregion

		#region Methods
		public void PostMessage(ref Message m)
		{
			base.WndProc(ref m);
		}
		#endregion
	}

	#endregion
}